package com.daqsoft.service.system;

import com.daqsoft.dao.PermissionConfigDao;
import com.daqsoft.data.Module;
import com.daqsoft.data.PermissionConfig;
import com.daqsoft.dto.IViewTree;
import com.daqsoft.permission.Verify;
import com.daqsoft.permission.VerifyType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.transaction.Transactional;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 周麟东 on 10:24
 */
@Service
@Transactional
public class PermissionManageService implements ApplicationListener<ContextRefreshedEvent> {

    private Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private PermissionConfigDao permissionConfigDao;
    @Autowired
    private ModuleService moduleService;

    private static List<IViewTree> pathTree = new ArrayList<>();
    /**
     * 地址列表 , key是url , value 是名称
     */
    private static Map<String, String> paths = new HashMap<>();

    public List<IViewTree> getPathTreeByModuleId(int moduleId) {
        List<PermissionConfig> list = getByModuleId(moduleId);
        for (IViewTree iViewTree : pathTree) {
            for (IViewTree viewTree : iViewTree.getChildren()) {
                viewTree.setChecked(false);
                for (PermissionConfig permissionConfig : list) {
                    if (Objects.equals(permissionConfig.getPath(), viewTree.getId())) {
                        viewTree.setChecked(true);
                        break;
                    }
                }
            }
        }
        return pathTree;
    }

    public List<PermissionConfig> getByModuleId(int moduleId) {
        return getAll().stream().filter(p -> p.getModule().getId() == moduleId).collect(Collectors.toList());
    }

    public void save(int moduleId, String[] path) {
        //先删除
        permissionConfigDao.deletePermissionConfigByModuleId(moduleId);
        for (String s : path) {
            PermissionConfig permissionConfig = new PermissionConfig();
            Module module = moduleService.get(moduleId);
            permissionConfig.setModule(module);
            permissionConfig.setName(paths.get(s));
            permissionConfig.setPath(s);
            save(permissionConfig);
        }
    }

    public List<PermissionConfig> getAll() {
        return permissionConfigDao.findAll();
    }

    public PermissionConfig save(PermissionConfig permissionConfig) {
        permissionConfig = permissionConfigDao.save(permissionConfig);
        return permissionConfig;
    }

    public void remove(int id) {
        permissionConfigDao.delete(id);
    }


    public List<PermissionConfig> getEngineByModuleId(int moduleId) {
        return getAll().stream().filter(p -> p.getModule().getId() == moduleId).collect(Collectors.toList());
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        ApplicationContext context = event.getApplicationContext();
        Map<String, Object> beans = context.getBeansWithAnnotation(Verify.class);
        for (Object o : beans.values()) {
            IViewTree iViewTree = new IViewTree();
            Verify v = o.getClass().getSuperclass().getDeclaredAnnotation(Verify.class);
            if (v == null) {
                log.error("无法获取类注解信息! class = {}", o.getClass().getName());
                continue;
            }
            RequestMapping r = o.getClass().getSuperclass().getDeclaredAnnotation(RequestMapping.class);
            if (r.value().length == 0) {
                log.error("类 {} requestMapping 没有值", o.getClass().getSuperclass());
                continue;
            }
            StringBuilder id = new StringBuilder(r.value()[0]);
            iViewTree.setId(id.toString());
            iViewTree.setTitle(v.desc());
            iViewTree.setExpand(true);
            Method[] methods = o.getClass().getSuperclass().getMethods();
            List<IViewTree> children = new ArrayList<>();
            for (Method method : methods) {
                Verify verify = method.getDeclaredAnnotation(Verify.class);
                if (verify == null) {
                    continue;
                }
                if (verify.value() != VerifyType.HAVE_PERMISSION) {
                    continue;
                }
                RequestMapping requestMapping = method.getDeclaredAnnotation(RequestMapping.class);
                if (requestMapping == null) {
                    continue;
                }
                if (requestMapping.value().length == 0) {
                    log.error("类方法 {}.{}() requestMapping 没有值", method.getClass().getName(), method.getName());
                    continue;
                }
                IViewTree child = new IViewTree();
                if (!id.toString().contains("/")) {
                    id.insert(0, "/");
                }
                String childId = requestMapping.value()[0];
                if (!childId.contains("/")) {
                    childId = "/" + childId;
                }
                child.setId(id + childId);
                child.setTitle(verify.desc());
                paths.put(id + childId, verify.desc());
                children.add(child);
            }
            iViewTree.setChildren(children);
            pathTree.add(iViewTree);
        }
    }


    public List<PermissionConfig> getEngineByPath(String path) {
        return getAll().stream().filter(p -> p.getPath().equals(path)).collect(Collectors.toList());
    }
}
